#!/usr/bin/env python

import os
import sys
import csv
import math
import random
import operator

def help ():
	print "Usage: \n"
	print "generator.py dir_to_patients [signal_numbers]"
	print "\tSignal nuber should be splited by whitespace"

def readData(filePath, signals, fndata):
	with open(filePath) as fp:
		for line in fp.readlines():
			nline = []
			if len(signals) == 0:
				signals = range(0, len(line.split()))
			for w in operator.itemgetter(*signals)(line.split()):
				try: 
					nw = float(w)
				except ValueError:
					nw = 0.0
				
				if (math.isnan(nw) or math.isinf(nw)):
					nw = 0.0
				
				nline.append (nw)
			fndata.append (nline)
			
def scaleValues (bc, fam, control):
	maxValues = bc[0][:]
	minValues = bc[0][:]
	for line in bc:
		for j in range(0,len(line)):
			maxValues[j] = max(maxValues[j], line[j])
			minValues[j] = min(minValues[j], line[j])
			
	for line in fam:
		for j in range(0,len(line)):
			maxValues[j] = max(maxValues[j], line[j])
			minValues[j] = min(minValues[j], line[j])
	for line in control:
		for j in range(0,len(line)):
			maxValues[j] = max(maxValues[j], line[j])
			minValues[j] = min(minValues[j], line[j])
			
	for line in bc:
		for j in range(0,len(line)):
			if ((maxValues[j]-minValues[j]) == 0):
				line[j] = 0
			else:
				line[j] = (line[j]-minValues[j])/(maxValues[j]-minValues[j])
	for line in fam:
		for j in range(0,len(line)):
			if ((maxValues[j]-minValues[j]) == 0):
				line[j] = 0
			else:
				line[j] = (line[j]-minValues[j])/(maxValues[j]-minValues[j])
	for line in control:
		for j in range(0,len(line)):
			if ((maxValues[j]-minValues[j]) == 0):
				line[j] = 0
			else:
				line[j] = (line[j]-minValues[j])/(maxValues[j]-minValues[j])
				
	outFile  = open ("scaleValues.dat", "w")
	csvWriter = csv.writer (outFile, delimiter=' ',  lineterminator='\n')
	csvWriter.writerow (maxValues)
	csvWriter.writerow (minValues)
	outFile.close();
				
def writeData (data, illnes, outFile):
	csvWriter = csv.writer (outFile, delimiter=' ',  lineterminator='\n')
	for line in data:
		csvWriter.writerow (line)
		csvWriter.writerow (illnes)
				
def main ():
	if (len(sys.argv) == 1):
		help()
		exit()
	
	patientDir = os.path.realpath(sys.argv[1])
	BCList = map (lambda x: os.path.join(patientDir, "BC", x), os.listdir (os.path.join(patientDir, "BC")))
	FAMList = map (lambda x: os.path.join(patientDir, "FAM", x), os.listdir (os.path.join(patientDir, "FAM")))
	ControlList = map (lambda x: os.path.join(patientDir, "Control", x), os.listdir (os.path.join(patientDir, "Control")))
	filesList = BCList + FAMList + ControlList;
	
	signals = map (int, sys.argv[2:])

	resBC = []
	resFAM = []
	resControl = []
	
	for i in filesList:
		if (i.find("Control") != -1):
			readData (i, signals, resBC)
		if (i.find("FAM") != -1):
			readData (i, signals, resFAM)
		if (i.find("BC") != -1):
			readData (i, signals, resControl)
			
	scaleValues (resBC, resFAM, resControl)
	
	
	trainBC = random.sample(range(0, len(resBC)), int (len(resBC) * 0.7))
	trainFAM = random.sample(range(0, len(resFAM)), int (len(resFAM) * 0.7))
	trainControl = random.sample(range(0, len(resControl)), int (len(resControl) * 0.7))
	
	testBC = filter (lambda x: x not in trainBC, range(0, len(resBC)))
	testFAM = filter (lambda x: x not in trainFAM, range(0, len(resFAM)))
	testControl = filter (lambda x: x not in trainControl, range(0, len(resControl)))
		
	f = open ("train.fndata", "w")
	f.write (str(len(trainBC) + len(trainFAM) + len(trainControl)) + " " + str(len(resBC[0])) + " 3\n")
	writeData (operator.itemgetter(*trainBC)(resBC), [1,0,0], f)
	writeData (operator.itemgetter(*trainFAM)(resFAM), [0,1,0], f)
	writeData (operator.itemgetter(*trainControl)(resControl), [0,0,1], f)
	f.close()
	
	f = open ("test.fndata", "w")
	f.write (str(len(testBC) + len(testFAM) + len(testControl)) + " " + str(len(resBC[0])) + " 3\n")
	writeData (operator.itemgetter(*testBC)(resBC), [1,0,0], f)
	writeData (operator.itemgetter(*testFAM)(resFAM), [0,1,0], f)
	writeData (operator.itemgetter(*testControl)(resControl), [0,0,1], f)
	f.close()
	
	print "Sucessfuly created train.fndata and test.fndata\n"
	
if __name__ == "__main__": main()
